package com.zzzy.server.service;

import com.zzzy.common.exception.WarningException;
import com.zzzy.common.util.IPUtil;
import com.zzzy.framework.dto.LoginUser;
import com.zzzy.server.common.cache.VerifyCodeCache;
import com.zzzy.server.common.util.AuthenticationContextHolder;
import com.zzzy.server.vo.LoginReq;
import com.zzzy.sys.dao.entity.UserLoginLog;
import com.zzzy.sys.dao.mapper.UserLoginLogMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;

@Service
public class LoginService {

    @Resource
    private UserLoginLogMapper userLoginLogMapper;
    @Resource
    private VerifyCodeCache verifyCodeCache;
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private TokenService tokenService;

    public String login(LoginReq loginReq){
        //验证码校验
        validateCaptcha(loginReq.getVerifyKey(), loginReq.getVerifyCode());

        String username = loginReq.getUsername();
        // 用户验证
        Authentication authentication;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, loginReq.getPassword());
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用 UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            throw new WarningException(e.getMessage());
        } finally {
            AuthenticationContextHolder.clearContext();
        }
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        addLoginLog(loginUser.getId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

    private void addLoginLog(Long userId) {
        UserLoginLog userLoginLog = new UserLoginLog();
        userLoginLog.setUserId(userId);
        userLoginLog.setLoginTime(LocalDateTime.now());
        userLoginLog.setIp(IPUtil.getUserIP());
        userLoginLogMapper.insert(userLoginLog);
    }

    private void validateCaptcha(String verifyKey, String verifyCode) {
        String errorMsg = "";
        String strRandomVerCode = verifyCodeCache.getVerifyCode(verifyKey);
        if(StringUtils.isBlank(strRandomVerCode)){
            errorMsg = "验证码已过期，请重新输入。";
        }else if(!StringUtils.equalsIgnoreCase(strRandomVerCode, verifyCode)){
            errorMsg = "验证码错误，请重新输入。";
        }
        if (StringUtils.isNotBlank(errorMsg)){
            throw new WarningException(errorMsg);
        }
        verifyCodeCache.removeVerifyCode(verifyKey);
    }
}
